# -*- coding: utf-8 -*-
# @Time    : 2024/7/1 15:25
# @Author  : yujiahao
# @File    : 11_numpy_view_cppy.py
# @description:NumPy副本和视图

'''
对 NumPy 数组执行些函数操作时，其中一部分函数会返回数组的副本，而另一部分函数则返回数组的视图。

其实从内存角度来说，副本就是对原数组进行深拷贝，新产生的副本与原数组具有不同的存储位置。而视图可理解为对数组的引用，它和原数组有着相同的内存位置。

'''

import numpy as np

# todo 1、赋值操作
# 赋值操作是数组引用的一种方法。例如，将数组 a 赋值给变量 b，
# 被赋值后的变量 b 与 a 具有相同的内存 id。
# 因此，无论操作 a 或 b 中的哪个数组，另一个数组也会受到影响。

a = np.array([[1, 2, 3, 4], [9, 0, 2, 3], [1, 2, 3, 19]])
print("原数组")
print(a)
print("a数组的ID:\t", id(a))

b = a
print("数组b的ID:\t", id(b))

# 修改 b 数组的形状
b.shape = 4, 3
print("b数组形状的更改也会反映到a数组上:\n")
print(a)

print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

# todo 1.1 ndarray.view()
# ndarray.view() 返回一个新生成的数组视图。视图是原数组的浅拷贝，
# 因此对视图的修改会影响原数组，但视图本身是一个新的对象，有不同的 id。

a = np.array([[1, 2, 3, 4], [9, 0, 2, 3], [1, 2, 3, 19]])
print("原数组\n")
print(a)
print("数组a的ID:\t", id(a))

b = a.view()
print("数组b的ID:\t", id(b))

# 打印 b 数组
print('\n打印 b 数组\n', b)

# 修改 b 数组的形状
b.shape = 4, 3
print("原数组a\n")
print(a)
print("新数组b\n")
print(b)

print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

# todo 2、 切片创建视图

# 使用切片可以创建视图数组，若要修改视图的内容会影响到原数组。

arr = np.arange(10)
print('数组arr：\n')
print(arr)

# 创建切片并修改原数组 arr
a = arr[3:]
b = arr[3:]
a[1] = 123
b[2] = 234
print('切片修改arr原数组：\n')
print(arr)

print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

# todo 2.1 ndarray.copy()
# 该方法返回原数组的副本，对副本的修改不会影响到原数组。

a = np.array([[1, 2, 3, 4], [9, 0, 2, 3], [1, 2, 3, 19]])
print("原数组\n", a)
print("a数组ID:\t", id(a))

b = a.copy()
print("b数组ID:\t", id(b))

# 打印经过 copy 方法的 b 数组
print('打印经过 copy 方法的 b 数组\n', b)

# 修改 b 数组的形状
b.shape = 4, 3
print("原数组a\n", a)
print("经过copy方法的b数组\n", b)
